package de.stefanocke.roo.wicket.base;

import java.util.Map;

import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.springframework.roo.classpath.PhysicalTypeMetadata;
import org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails;
import org.springframework.roo.classpath.itd.AbstractItdTypeDetailsProvidingMetadataItem;
import org.springframework.roo.model.JavaType;

import de.stefanocke.roo.wicket.MidUtils;
import de.stefanocke.roo.xtend.ItdBuilder;

public abstract class ItdMetadataBase<AV> extends AbstractItdTypeDetailsProvidingMetadataItem implements ItdMetadata,
		PropertyFileChanges {

	private AV annotationValues;
	private Map<String, ClassOrInterfaceTypeDetails> stereotypes;
	private ItdBuilder itdBuilder;

	public ItdMetadataBase(ItdMetadataCreationParams<AV> cmcp, ItdBuilder itdBuilder) {
		super(cmcp.getMid(), cmcp.getAspectName(), cmcp.getGovernorPhysicalTypeMetadata());
		Validate.isTrue(getMidUtils().isValid(cmcp.getMid()), "Metadata identification string '" + cmcp.getMid()
				+ "' does not appear to be a valid");
		this.annotationValues = cmcp.getAnnotationValues();
		this.stereotypes = cmcp.getStereotypes();
		this.itdBuilder = itdBuilder;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see de.stefanocke.roo.wicket.base.WicketItdMetadata#getMidUtils()
	 */
	@Override
	public MidUtils getMidUtils() {
		return MidUtils.get(this.getClass());
	}

	public AV getAnnotationValues() {
		return annotationValues;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see de.stefanocke.roo.wicket.base.ItdMetadata#getStereotypes()
	 */
	@Override
	public Map<String, ClassOrInterfaceTypeDetails> getStereotypes() {
		return stereotypes;
	}

	@Override
	public JavaType getDestination() {
		return destination;
	}

	@Override
	public PhysicalTypeMetadata getGovernor() {
		return governorPhysicalTypeMetadata;
	}

	public String toString() {
		final ToStringBuilder builder = new ToStringBuilder(this);
		builder.append("identifier", getId());
		builder.append("valid", valid);
		builder.append("aspectName", aspectName);
		builder.append("destinationType", destination);
		builder.append("governor", governorPhysicalTypeMetadata.getId());
		builder.append("itdTypeDetails", itdTypeDetails);
		return builder.toString();
	}

	protected void buildItdTypeDetails() {
		itdBuilder.init(builder, governorTypeDetails, this);
		itdBuilder.build();

		// Create a representation of the desired output ITD
		itdTypeDetails = builder.build();
	}
	
	@Override
	public Map<String, String> getPropertiesToAdd() {
		if(itdBuilder instanceof PropertyFileChanges){
			return ((PropertyFileChanges) itdBuilder).getPropertiesToAdd();
		} else {
			return null;
		}
	}
	
	@Override
	public Map<String, String> getPropertiesToRename() {
		if(itdBuilder instanceof PropertyFileChanges){
			return ((PropertyFileChanges) itdBuilder).getPropertiesToRename();
		} else {
			return null;
		}
	}

}